﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using ScottPlot;
using ScottPlot.Plottable;
using Serilog.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using TMI85303.UI.Messages;

namespace TMI85303.UI.View
{
    /// <summary>
    /// SpeedPlotWin.xaml 的交互逻辑
    /// </summary>
    /// 
    [INotifyPropertyChanged]
    public partial class SpeedPlotWin : Window
    {
        public double[] data = new double[100000];
        public int nextDataIndex = 1;
        private SignalPlot signalPlot;
        private readonly MarkerPlot HighlightedPoint;
        private int LastHighlightedIndex = -1;

        private readonly DispatcherTimer RenderTimer = new() { Interval = TimeSpan.FromMilliseconds(100) };

        [ObservableProperty]
        private double? mouseValY;

        private bool PointCatch = false;

        public SpeedPlotWin()
        {
            InitializeComponent();
            
            signalPlot = wpfPlot1.Plot.AddSignal(data);
            wpfPlot1.Plot.Title("Real time speed");
            wpfPlot1.Plot.YLabel("Speed");
            wpfPlot1.Plot.XLabel("Time");
            //WpfPlot1.Plot.AxisAutoX(margin: 0.2);
            //WpfPlot1.Plot.AxisAutoY(margin: 0);
            signalPlot.LineColor = System.Drawing.Color.LightBlue;
            signalPlot.LineWidth = 3;
            signalPlot.MarkerColor = System.Drawing.Color.Blue;
            ////wpfPlot1.Plot.SetAxisLimits(yMin: -1, yMax: 2.5);
            wpfPlot1.Plot.AxisAuto();
            signalPlot.MaxRenderIndex = 0; //初始只渲染一个点


            HighlightedPoint = wpfPlot1.Plot.AddPoint(0, 0);
            HighlightedPoint.Color = System.Drawing.Color.Red;
            HighlightedPoint.MarkerSize = 10;
            HighlightedPoint.MarkerShape = ScottPlot.MarkerShape.openCircle;
            HighlightedPoint.IsVisible = false;


            wpfPlot1.Refresh();

            
            RenderTimer.Tick += Render;
            RenderTimer.Start();


            Closed += (sender, args) =>
            {
                WeakReferenceMessenger.Default.Send<SpeedPlotClosedMesg, int>(new(), (int)MesgToken.MainWindowToken);
                RenderTimer?.Stop();
            };
            WeakReferenceMessenger.Default.Register<SpeedPlotPointCatch, int>(this, (int)MesgToken.SpeedPlotWinToken, (s, e) =>
            {
                PointCatch = e.Open;
                HighlightedPoint.IsVisible = e.Open;
            });

        }


        private void Render(object? sender, EventArgs e)
        {
            if (AutoAxisCheckbox.IsChecked == true)
                wpfPlot1.Plot.AxisAuto();
            wpfPlot1.Refresh();
        }

        public void UpdateData(double insertValue)
        { 
            if (nextDataIndex >= data.Length)
            {
                wpfPlot1.Plot.Clear();

                Array.Clear(data, 0, data.Length);
                nextDataIndex = 1;
                signalPlot = wpfPlot1.Plot.AddSignal(data);
            }

            data[nextDataIndex] = insertValue;
            signalPlot.MaxRenderIndex = nextDataIndex;
            nextDataIndex += 1;
        }

        private void DisableAutoAxis(object sender, RoutedEventArgs e)
        {
            wpfPlot1.Plot.AxisAuto(verticalMargin: .5);
            var oldLimits = wpfPlot1.Plot.GetAxisLimits();
            wpfPlot1.Plot.SetAxisLimits(xMax: oldLimits.XMax + 1000);
        }

        private void wpfPlot1_MouseMove(object sender, MouseEventArgs e)
        {
            if (!PointCatch) return;
            (double mouseCoordX, _) = wpfPlot1.GetMouseCoordinates();
            (double pointX, double pointY, int pointIndex) = signalPlot.GetPointNearestX(mouseCoordX);

            HighlightedPoint.X = pointX;
            HighlightedPoint.Y = pointY;

            // render if the highlighted point chnaged
            if (LastHighlightedIndex != pointIndex)
            {
                LastHighlightedIndex = pointIndex;
                MouseValY = pointY;
                wpfPlot1.Refresh();
            }

        }
    }


}
